/*
 * RevenueSource DAO.java
 *
 * Created on February 13, 2007
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */
/**
 * Version 1.0
 *
 * The data base access object for revenue sources
 */
package finalintex2web;
import java.util.*;
import java.io.*;
import java.sql.*;

/**
 * database access object for ravenue sources
 */
    public abstract class RevenueSourceDAO {
   

    /** Creates a new instance of RevenueSourceDAO */
    public RevenueSourceDAO() {
    }
  
    /////////////////////////////////
    ///   CREATE
    /**
     * 
     * @return 
     */
    protected abstract  RevenueSourceBO create();
    /////////////////////////////////////
    ///   READ
    /**
     * 
     * @param id 
     * @throws intex2.DataException 
     * @throws intex2.ConnectionPoolException 
     * @return 
     */
    public RevenueSourceBO read(String id) throws DataException,ConnectionPoolException{
        
        try {
            Connection conn = ConnectionPool.getInstance().get();
            RevenueSourceBO revsrc = (RevenueSourceBO)read(id,conn);
            ConnectionPool.getInstance().release(conn);
            return revsrc;
        }catch (SQLException e) {
            // rollback
            throw new DataException("SQL error from read 1", e);
        }catch (ConnectionPoolException e){
            throw new ConnectionPoolException("Connection pool error in read 1", e);
        }
    }
    private RevenueSourceBO read(String id, Connection conn) throws SQLException, DataException, ConnectionPoolException{

        if(Cache.getInstance().containsKey(id)){
            RevenueSourceBO revsrc = (RevenueSourceBO)Cache.getInstance().get(id);
            return revsrc;
            }      
           try{        
           PreparedStatement stmt = conn.prepareStatement("SELECT * FROM RevenueSource WHERE id=?");
           stmt.setString(1,id);
           ResultSet rs =  stmt.executeQuery();
           
           ConnectionPool.getInstance().release(conn);
            
            if (rs.next()) {
                RevenueSourceBO revsrc = (RevenueSourceBO)Cache.getInstance().get(id);
                revsrc.setPrice(rs.getDouble("price"));
                Cache.getInstance().put(id,revsrc);      
                revsrc.setIndb(true);
                stmt.close();
                return revsrc;
               

            }else{
                throw new DataException("RevenueSourceBO was not found in the database.");
            }
           
            }catch (ConnectionPoolException e){
                throw new ConnectionPoolException("Could not retrieve a connection from the database", e);
            
            }catch (SQLException e){
                throw new DataException("SQL error", e);
            }
    }
    //////////////////////////////////
    ///   UPDATE
    /**
     * 
     * @param revsrc 
     * @throws intex2.DataException 
     * @throws intex2.ConnectionPoolException 
     */
    public synchronized void save(RevenueSourceBO revsrc) throws DataException,ConnectionPoolException {
        
        
        try {
            Connection conn = ConnectionPool.getInstance().get();
            save(revsrc,conn);
            ConnectionPool.getInstance().release(conn);
        }catch (SQLException e) {
            //rollback
            throw new DataException("Could not retrieve record for id=" + revsrc.getId(), e);
            
            }catch (ConnectionPoolException e){
            e.printStackTrace();
        }
        
        // release the connection back to the pool
        return;
    }
     synchronized void save(RevenueSourceBO revsrc, Connection conn) throws SQLException, DataException, ConnectionPoolException {
        // check the dirty flag in the RevenueSourceDBO.  if it is dirty, 
        // run update or insert
        if (revsrc.isDirty()) {
            if (revsrc.isIndb()) {
               update(revsrc, conn);
            }else{
               insert(revsrc, conn);
            }
            revsrc.setDirty(false);
        Cache.getInstance().touch(revsrc.getId());
     
        }
        
    }
 private synchronized void update(RevenueSourceBO revsrc, Connection conn) throws SQLException, DataException, ConnectionPoolException {
        PreparedStatement stmt = conn.prepareStatement("UPDATE RevenueSource SET sourcetype = ?, price = ? WHERE id=? ");
        stmt.setString(1,revsrc.getType());
        stmt.setDouble(2,revsrc.getPrice());
        stmt.setString(3,revsrc.getId());
        stmt.execute();
        stmt.close();
        ConnectionPool.getInstance().release(conn);
    }
     
    /**
     * This method is really a part of save(bo, conn) above.  It could be
     * embedded directly in it, but I've separated it into it's own method
     * to isolate the SQL insert statement and make it more readable.  But
     * logically, it's really just a part of save.
     */
    private synchronized void insert(RevenueSourceBO revsrc, Connection conn) throws SQLException, DataException, ConnectionPoolException {
        // do the insert SQL statement
        PreparedStatement stmt = conn.prepareStatement("INSERT INTO RevenueSource (sourcetype,price,id) VALUES ( ?,?,?)");
        stmt.setString(1,revsrc.getType());
        stmt.setDouble(2,revsrc.getPrice());
        stmt.setString(3,revsrc.getId());
        stmt.execute();
        stmt.close();
        // tell the RevenueSourceDBO that it's now in the db (so we call update next time not insert)
        revsrc.setIndb(true);
        ConnectionPool.getInstance().release(conn);
    }
}